package thread3;

import java.util.concurrent.TimeUnit;

class HoldThread implements Runnable {
    private final String lock1;
    private final String lock2;

    public HoldThread(String lock1, String lock2) {
        this.lock1 = lock1;
        this.lock2 = lock2;
    }

    @Override
    public void run() {
        synchronized (lock1) {
            System.out.println(Thread.currentThread().getName() + "\t" + "持有" + lock1 + "尝试获得" + lock2);
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            synchronized (lock2) {
                System.out.println(Thread.currentThread().getName() + "\t" + "持有" + lock2 + "尝试获得" + lock1);
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

public class DeadLockDemo {
    public static void main(String[] args) {
        /*
        死锁编码和定位分析
        死锁是指两个或者两个以上的线程在执行过程中，因争夺资源而造成的一种互相等待的现象，如果没有外力干涉，那么它们都将无法推进下去，
        如果系统资源充足，进程的资源请求都能得到满足，死锁出现的可能性就很低，否则就会因为争夺有限的资源而陷入死锁
        */
        String lock1 = "lock1";
        String lock2 = "lock2";

        new Thread(new HoldThread(lock1, lock2), "a").start();
        new Thread(new HoldThread(lock2, lock1), "b").start();

        /*
        windows下的java运行程序也有类似ps的查看进行的命令，但是我们需要查看的只是java
        jps = java版本的ps
        一般来说，jps的进程号都会以文件的形式存储在Temp目录，比如win10的路径就是C:\Users\qxf\AppData\Local\Temp\hsperfdata_qxf
        我们可以通过 jps -l 查看类名，然后再用 jstack 进程号 查看堆栈信息
        如果提示：Found 1 deadlock.
        那么就是产生死锁了

        Found one Java-level deadlock:
        =============================
        "b":
          waiting to lock monitor 0x000001b724b29c78 (object 0x00000000d6202368, a java.lang.String),
          which is held by "a"
        "a":
          waiting to lock monitor 0x000001b724b2c458 (object 0x00000000d62023a0, a java.lang.String),
          which is held by "b"

        Java stack information for the threads listed above:
        ===================================================
        "b":
                at thread3.HoldThread.run(DeadLockDemo.java:25)
                - waiting to lock <0x00000000d6202368> (a java.lang.String)
                - locked <0x00000000d62023a0> (a java.lang.String)
                at java.lang.Thread.run(Thread.java:748)
        "a":
                at thread3.HoldThread.run(DeadLockDemo.java:25)
                - waiting to lock <0x00000000d62023a0> (a java.lang.String)
                - locked <0x00000000d6202368> (a java.lang.String)
                at java.lang.Thread.run(Thread.java:748)

        Found 1 deadlock.

        找到原因后，重启系统，找到对应的业务逻辑修改后，重启就能解决死锁
        */
    }
}
